#!/usr/bin/env python
# -*- coding: utf-8 -*-

u'''
pps_config是PyProxySwitch(PPS)的配置程序，可以为PPS添加或者删除代理。

用法：

添加代理(仅支持添加单个代理，批量添加请使用src目录下的batch_add_proxy.bat，其用法请见README_CN.txt)：

  pps_config add 代理名称 代理地址:端口 用户名:密码 
       代理名称可以是自定义的任何名字，[用户名:密码]仅用于需要认证的代理，一般情况下不需要，可省略。
  例如：pps_config add test1 test1.com:8080 
        pps_config add test2 test2.com:8080 user:pass
  或者：pps_config add test3 1.2.3.4:80


删除代理(支持批量删除)：

  pps_config del 代理名称1 代理名称2 ...
  例如：pps_config del test1
        pps_config del test1 test2 test3

'''

__author__= 'Kder'
__copyright__ = 'Copyright 2009-2010 Kder'
__credits__ = ['Kder']

__version__ = '1.1.1'
__date__ = '2010-8-7'
__maintainer__ = "Kder"
__email__ = '<kderlin (#) gmail dot com>'
__url__ = 'http://www.kder.info'
__license__ = 'Apache License, Version 2.0'
__status__ = 'Release'

import sys
import os
import re
import locale
import codecs
import traceback

SYS_ENCODING = locale.getdefaultlocale()[1]
reload(sys)
sys.setdefaultencoding('utf-8')

def pps_output(msg, dest = 'stdout'):
    if dest == 'stderr':
        sys.stderr.write(msg.encode(SYS_ENCODING))
    else:
        sys.stdout.write(msg.encode(SYS_ENCODING))
        
if __name__ == '__main__':
    if 'pps_config.exe' in sys.path[0]:
        PROGRAM_PATH = os.path.dirname(sys.path[0]).decode(SYS_ENCODING)
    else:
        PROGRAM_PATH = sys.path[0].decode(SYS_ENCODING)
    CONF = os.path.join(PROGRAM_PATH, '..', 'cfg', 'PPS.conf')
    sys.path.append(os.path.join(PROGRAM_PATH, '..', 'src'))
    import pyetc
    config = pyetc.load(CONF)
    #~ os.chdir(sys.path[0])
    
    usage = __doc__
    usage_add = u'''
用法：

添加代理(仅支持添加单个代理，批量添加请使用src目录下的batch_add_proxy.bat，其用法请见README_CN.txt)：

  pps_config add 代理名称 代理地址:端口 用户名:密码
  
      代理名称可以是自定义的任何名字，[用户名:密码]仅用于需要认证的代理，一般情况下不需要，可省略
      
  例如：pps_config add test1 test1.com:8080 
        pps_config add test2 test2.com:8080 user:pass
  或者：pps_config add test3 1.2.3.4:80
            '''
    try:
        action = sys.argv[1]
    except:
        action = None

    if action == 'add':

        try:
            proxy_name = sys.argv[2]
            proxy_name_decoded = proxy_name.decode(SYS_ENCODING)
            proxy_address = sys.argv[3]
            proxy = proxy_address.split(':')
            proxy_auth = []
            try:
                if sys.argv[4] != None:
                    proxy_auth = sys.argv[4].split(':')
            except:
                pass
        except:
            pps_output(usage_add)
            sys.exit(1)
        try:    
            if proxy_auth != []:
                conf_polipo = '''parentProxy = ''' + proxy_address + '''
parentAuthCredentials = ''' + proxy_auth[0] +  ':' + proxy_auth[1] + '''
proxyPort = ''' + config.LOCAL_PORT
        
                conf_3proxy = '''internal 127.0.0.1
auth iponly
allow * 127.0.0.1
''' + 'parent 1000 http ' + proxy[0] + ' ' + proxy[1] + ' ' + proxy_auth[0] + ' ' + proxy_auth[1] + '''
proxy -n -a -p''' + config.LOCAL_PORT
            else:
                conf_polipo = '''parentProxy = ''' + proxy_address + '''
proxyPort = ''' + config.LOCAL_PORT
        
                conf_3proxy = '''internal 127.0.0.1
auth iponly
allow * 127.0.0.1
''' + 'parent 1000 http ' + proxy[0] + ' ' + proxy[1] + '''
proxy -n -a -p''' + config.LOCAL_PORT            
        except:
            pps_output(usage_add)
            sys.exit(2)
        f = codecs.open(os.path.join(PROGRAM_PATH, '..', 'cfg', 'polipo', proxy_name_decoded + '.conf'),'w','utf-8')
        f.write(conf_polipo.decode('utf-8'))
        f.close()

        f = codecs.open(os.path.join(PROGRAM_PATH, '..', 'cfg', '3proxy', proxy_name_decoded + '.conf'),'w','utf-8')
        f.write(conf_3proxy.decode('utf-8'))
        f.close()

        f = codecs.open(CONF,'r','utf-8')
        config_content = f.read()
    #    if proxy_name in config_content: #or proxy_name in config.CFG_iprelay
        if proxy_name in config.CFG_3proxy  or proxy_name in config.CFG_polipo:
            pps_output(u'\n 代理已存在，或者名称冲突，请指定其他名称。', 'stderr')
            f.close()
            sys.exit(2)
        r = config_content.replace(u'}#POLIPO', u'\'' + proxy_name_decoded + u'\':[\'' + proxy_name_decoded + u'\'],}#POLIPO'
        ).replace(u'}#3PROXY', u'\'' + proxy_name_decoded + u'\':[\'' + proxy_name_decoded + u'\'],}#3PROXY'
        ).replace(u'}#IP_RELAY',u'\'' + proxy_name_decoded + u'\':[\'' + proxy[0].decode('utf-8') + u'\',\'' + proxy[1].decode('utf-8') + u'\'],}#IP_RELAY') #用替换实现追加
        #print r
        f.close()

        f = codecs.open(CONF,'w','utf-8')
        f.write(r)
        f.close()

        pps_output(u'"%s" 添加成功!\n' % proxy_name_decoded)
        #~ print conf_3proxy
        #
    elif action == 'del':
        try:
            f = codecs.open(CONF,'r','utf-8')
            config_content = f.read()
            f.close()
        ##    r = config_content.replace('\'' + proxy_name + '\':[\'' + proxy_name + '\'],', '')
            #~ proxy_name = sys.argv[2]
            for proxy_name in sys.argv[2:]: #用替换实现删除代理项
                proxy_name_decoded = proxy_name.decode(SYS_ENCODING)
                rep = u'\'' + proxy_name_decoded + u"':\[.+?'\],"
                #~ print rep
                config_content = re.sub(rep, '', config_content) 
                pps_output(u'正在删除代理 "%s"  ……\n' % proxy_name_decoded)

            f = codecs.open(CONF, 'w' , 'utf-8')
            f.write(config_content)
            f.close()

            for proxy_name in sys.argv[2:]: #移除对应的配置文件
                try:
                    os.remove(os.path.join(PROGRAM_PATH, '..', 'cfg', 'polipo', 
                              proxy_name + '.conf'))
                    os.remove(os.path.join(PROGRAM_PATH, '..', 'cfg', '3proxy', 
                              proxy_name + '.conf'))
                except:
                    pps_output(u'\n删除代理时出错：配置文件不存在，或者没有删除权限。', 'stderr')
                    sys.exit(3)

        except IOError:
            pps_output(u'\n打开配置文件出错，请检查cfg目录下的PPS.conf是否存在以及是否有权限读写。', 'stderr')
            sys.exit(5)
        except Exception,e:
            pps_output(str(e), 'stderr')
            traceback.print_exc()
            pps_output(u'''\n用法
删除代理(支持批量删除)：

  pps_config del 代理名称1 代理名称2 ...
  
  例如：pps_config del test1
        pps_config del test1 test2 test3
        ''')
            sys.exit(1)

        pps_output(u'删除成功！\n')
    else:
        pps_output(usage)
